1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39 import javax.net.ssl.*;
40 import javax.net.ssl.SSLEngineResult.*;
41 import java.io.*;
42 import java.security.*;
43 import java.nio.*;
44 import java.util.*;
45
46 public class TestAllSuites {
47
48 private static boolean debug = false;
49
50 private SSLContext sslc;
51 private SSLEngine ssle1;
52 private SSLEngine ssle2;
53
54 private static String pathToStores = "../../../../../etc";
55 private static String keyStoreFile = "keystore";
56 private static String trustStoreFile = "truststore";
57 private static String passwd = "passphrase";
58
59 private static String keyFilename =
60 System.getProperty("test.src", "./") + "/" + pathToStores +
61 "/" + keyStoreFile;
62 private static String trustFilename =
63 System.getProperty("test.src", "./") + "/" + pathToStores +
64 "/" + trustStoreFile;
65
66 private ByteBuffer appOut1;
67 private ByteBuffer appIn1;
68 private ByteBuffer appOut2;
69 private ByteBuffer appIn2;
70
71 private ByteBuffer oneToTwo;
72 private ByteBuffer twoToOne;
73
74 String [][] protocols = new String [][] {
75 { "SSLv3" },
76 { "TLSv1" },
77 { "SSLv3", "SSLv2Hello"},
78 { "TLSv1", "SSLv2Hello"}
79 };
80
81
82
83
84
85 private void createSSLEngines() throws Exception {
86 ssle1 = sslc.createSSLEngine("client", 1);
87 ssle1.setUseClientMode(true);
88
89 ssle2 = sslc.createSSLEngine("server", 2);
90 ssle2.setUseClientMode(false);
91 }
92
93 private void test() throws Exception {
94
95 createSSLEngines();
96 String [] suites = ssle1.getSupportedCipherSuites();
97
98 for (int i = 0; i < suites.length; i++) {
99 for (int j = 0; j < protocols.length; j++) {
100 createSSLEngines();
101 runTest(suites[i], protocols[j]);
102 }
103 }
104 }
105
106 private void runTest(String suite, String [] protocols) throws Exception {
107
108 boolean dataDone = false;
109
110 System.out.println("======================================");
111 System.out.println("Testing: " + suite);
112 for (int i = 0; i < protocols.length; i++) {
113 System.out.print(protocols[i] + " ");
114 }
115
116
117
118
119 if (suite.startsWith("TLS_KRB5")) {
120 System.out.println("Ignoring Kerberized suite");
121 return;
122 }
123
124
125
126
127 if (suite.equals("TLS_EMPTY_RENEGOTIATION_INFO_SCSV")) {
128 System.out.println("Ignoring SCSV suite");
129 return;
130 }
131
132
133 if (!suite.contains("DH_anon")) {
134 ssle2.setNeedClientAuth(true);
135 }
136
137 String [] suites = new String [] { suite };
138
139 ssle1.setEnabledCipherSuites(suites);
140 ssle2.setEnabledCipherSuites(suites);
141
142 ssle1.setEnabledProtocols(protocols);
143 ssle2.setEnabledProtocols(protocols);
144
145 createBuffers();
146
147 SSLEngineResult result1;
148 SSLEngineResult result2;
149
150 Date start = new Date();
151 while (!isEngineClosed(ssle1) || !isEngineClosed(ssle2)) {
152
153 log("----------------");
154
155 result1 = ssle1.wrap(appOut1, oneToTwo);
156 result2 = ssle2.wrap(appOut2, twoToOne);
157
158 log("wrap1: " + result1);
159 log("oneToTwo = " + oneToTwo);
160 log("");
161
162 log("wrap2: " + result2);
163 log("twoToOne = " + twoToOne);
164
165 runDelegatedTasks(result1, ssle1);
166 runDelegatedTasks(result2, ssle2);
167
168 oneToTwo.flip();
169 twoToOne.flip();
170
171 log("----");
172
173 result1 = ssle1.unwrap(twoToOne, appIn1);
174 result2 = ssle2.unwrap(oneToTwo, appIn2);
175
176 log("unwrap1: " + result1);
177 log("twoToOne = " + twoToOne);
178 log("");
179
180 log("unwrap2: " + result2);
181 log("oneToTwo = " + oneToTwo);
182
183 runDelegatedTasks(result1, ssle1);
184 runDelegatedTasks(result2, ssle2);
185
186 oneToTwo.compact();
187 twoToOne.compact();
188
189
190
191
192
193 if (!dataDone && (appOut1.limit() == appIn2.position()) &&
194 (appOut2.limit() == appIn1.position())) {
195
196 checkTransfer(appOut1, appIn2);
197 checkTransfer(appOut2, appIn1);
198
199 log("Closing ssle1's *OUTBOUND*...");
200 ssle1.closeOutbound();
201 dataDone = true;
202 }
203 }
204
205
206
207
208
209 ssle1.closeInbound();
210 ssle1.closeOutbound();
211
212 ssle2.closeInbound();
213 ssle2.closeOutbound();
214
215 appOut1.rewind();
216 appIn1.clear();
217 oneToTwo.clear();
218
219 result1 = ssle1.wrap(appOut1, oneToTwo);
220 checkResult(result1);
221
222 result1 = ssle1.unwrap(oneToTwo, appIn1);
223 checkResult(result1);
224
225 System.out.println("Test Passed.");
226 System.out.println("\n======================================");
227
228 Date end = new Date();
229 elapsed += end.getTime() - start.getTime();
230
231 }
232
233 static long elapsed = 0;
234
235 private static void checkResult(SSLEngineResult result) throws Exception {
236 if ((result.getStatus() != Status.CLOSED) ||
237 (result.getHandshakeStatus() !=
238 HandshakeStatus.NOT_HANDSHAKING) ||
239 (result.bytesConsumed() != 0) ||
240 (result.bytesProduced() != 0)) {
241 throw new Exception("Unexpected close status");
242 }
243 }
244
245 public static void main(String args[]) throws Exception {
246
247 TestAllSuites tas;
248
249 tas = new TestAllSuites();
250
251 tas.createSSLEngines();
252
253 tas.test();
254
255 System.out.println("All Tests Passed.");
256 System.out.println("Elapsed time: " + elapsed / 1000.0);
257 }
258
259
260
261
262
263
264
265 public TestAllSuites() throws Exception {
266 sslc = getSSLContext(keyFilename, trustFilename);
267 }
268
269
270
271
272 private SSLContext getSSLContext(String keyFile, String trustFile)
273 throws Exception {
274
275 KeyStore ks = KeyStore.getInstance("JKS");
276 KeyStore ts = KeyStore.getInstance("JKS");
277
278 char[] passphrase = "passphrase".toCharArray();
279
280 ks.load(new FileInputStream(keyFile), passphrase);
281 ts.load(new FileInputStream(trustFile), passphrase);
282
283 KeyManagerFactory kmf = KeyManagerFactory.getInstance("SunX509");
284 kmf.init(ks, passphrase);
285
286 TrustManagerFactory tmf = TrustManagerFactory.getInstance("SunX509");
287 tmf.init(ts);
288
289 SSLContext sslCtx = SSLContext.getInstance("TLS");
290
291 sslCtx.init(kmf.getKeyManagers(), tmf.getTrustManagers(), null);
292
293 return sslCtx;
294 }
295
296 private void createBuffers() {
297
298
299 SSLSession session = ssle1.getSession();
300 int appBufferMax = session.getApplicationBufferSize();
301 int netBufferMax = session.getPacketBufferSize();
302
303 appIn1 = ByteBuffer.allocateDirect(appBufferMax + 50);
304 appIn2 = ByteBuffer.allocateDirect(appBufferMax + 50);
305
306 oneToTwo = ByteBuffer.allocateDirect(netBufferMax);
307 twoToOne = ByteBuffer.allocateDirect(netBufferMax);
308
309 appOut1 = ByteBuffer.wrap("Hi Engine2, I'm SSLEngine1".getBytes());
310 appOut2 = ByteBuffer.wrap("Hello Engine1, I'm SSLEngine2".getBytes());
311
312 log("AppOut1 = " + appOut1);
313 log("AppOut2 = " + appOut2);
314 log("");
315 }
316
317 private static void runDelegatedTasks(SSLEngineResult result,
318 SSLEngine engine) throws Exception {
319
320 if (result.getHandshakeStatus() == HandshakeStatus.NEED_TASK) {
321 Runnable runnable;
322 while ((runnable = engine.getDelegatedTask()) != null) {
323 log("running delegated task...");
324 runnable.run();
325 }
326 }
327 }
328
329 private static boolean isEngineClosed(SSLEngine engine) {
330 return (engine.isOutboundDone() && engine.isInboundDone());
331 }
332
333 private static void checkTransfer(ByteBuffer a, ByteBuffer b)
334 throws Exception {
335 a.flip();
336 b.flip();
337
338 if (!a.equals(b)) {
339 throw new Exception("Data didn't transfer cleanly");
340 } else {
341 log("Data transferred cleanly");
342 }
343
344 a.position(a.limit());
345 b.position(b.limit());
346 a.limit(a.capacity());
347 b.limit(b.capacity());
348 }
349
350 private static void log(String str) {
351 if (debug) {
352 System.out.println(str);
353 }
354 }
355 }